/*
 * Copyright (c) 2010-2011 Plugger Antonio Begue Ponce. All Rights Reserved.
 *
 * This file is part of Plugger Framework.
 *
 *  Plugger Framework is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License version 3 as published by
 *  the Free Software Foundation.
 *
 *  Plugger Framework is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with Plugger Framework.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.plugger.infrastructure.domainbase;

import com.jgoodies.binding.beans.Model;
import java.util.ArrayList;
import java.util.List;
import org.plugger.infrastructure.rules.IRule;

/**
 * An abstract superclass that provides the basis for domain entities
 * and allows the use of it as java beans.
 *
 * @author Antonio Begue
 * @version $Revision: 1.0 $
 *
 * @see     IRule
 * @see     KeyObject
 */
public abstract class EntityBase extends Model implements IEntity, IValidatableForPersistence {
    private Object key;
    private List<IRule> persistenceRules;

    /**
     * Constructs an empty <code>EntityBase</code>.
     */
    public EntityBase() {
        this(null);
    }

    /**
     * Constructs a <code>EntityBase</code> with the given key.
     *
     * @param key              the key of the entity
     */
    public EntityBase(Object key) {
        this.key = key;
        if (this.key == null) {
            this.key = EntityBase.newKey();
        }
        persistenceRules = new ArrayList<IRule>();
    }

    /**
     * The key is the connection between the entity and the persistence system.
     *
     * @return the key of the entity
     */
    public Object getKey() {
        return this.key;
    }
    
    /**
     * The key is generated automatically from the persistence system
     * only set the key when you know the persisted key.
     *
     * @param key the entity key to set
     */
    public void setKey(Object key) {
        this.key = key;
    }

    /**
     * Generates a key that represent a new entity never persisted.
     *
     * @return new key
     */
    public static Object newKey() {
        return KeyObject.getInstance().newKey();
    }

    /**
     * Verify if the entity has been persisted.
     *
     * @return true if the entity has never been persisted.
     */
    public boolean isNew() {
        return KeyObject.getInstance().isNew(getKey());
    }

    // <editor-fold defaultstate="collapsed" desc="IValidatableForPersistence Members">
    /**
     * Verify if the entity is valid for persistence
     * check every IRule inside persistenceRules.
     *
     * @return true only when all IRules inside persistenceRules are passed.
     */
    public Boolean isValidForPersistence() {
        return getBrokenPersistenceRules().isEmpty();
    }

    /**
     * A function that collect broken rules.
     *
     * @return A collection of broken rules.
     */
    public abstract List<IRule> getBrokenPersistenceRules();

    /**
     * Returns the collection of IRules
     *
     * @return the persistenceRules
     */
    public List<IRule> getPersistenceRules() {
        return persistenceRules;
    }

    /**
     * A function to initialize the persistence rules
     */
    public abstract void initializePersistenceRules();
    // </editor-fold>
}
